<?php
namespace Spay;

use Spay\Exception\SpayParamaterException;
use Spay\Spay;
use Spay\Exception\SpayCurlException;

abstract class ApiBase
{
    public function checkParams($params = null)
    {
        if ($params && !is_array($params)) {
            throw new SpayParamaterException('params must be arry');
        }
    }

    public function curlRequest($url, $method, $params = null, $options = null)
    {
        if (empty(Spay::$appId)) {
            throw  new SpayParamaterException('appid is not set');
        }
        $userAgent = [
            'spay_ver' => Spay::SPAY_VERSION,
            'api_ver' => Spay::API_VERSION,
            'lang' => 'php',
            'lang_ver' => phpversion(),
            'uname' => php_uname()
        ];
        $headers = [
            'X-Spay-Client-User-Agent' => json_encode($userAgent),
            'X-Spay-AppId' => Spay::$appId,
            'X-Spay-ApiVersion' => Spay::API_VERSION
        ];
        $method = strtolower($method);
        if (in_array($method, ["post", 'put'])) {
            $headers['Content-Type'] = 'application/json;charset=UTF-8';
        }
        if ($method == 'put') {
            $headers['X-HTTP-Method-Override'] = 'PUT';
        }

        $curlOpts = [];
        $toSign = '';
        $requestTime = time();
        $headers['X-Spay-Request-Time'] = $requestTime;
        $rawRequestBody = $params !== null ? json_encode($params) : '';
        $signedRequestBody = false;
        //AES-256-cs
        if (Spay::$appSecretKey) {
            $signedRequestBody = openssl_encrypt($rawRequestBody, "aes-256-cbc", Spay::$appSecretKey);
            if ($signedRequestBody === false)
                throw  new SpayParamaterException('generate signature failed');
            $toSign = $signedRequestBody . $requestTime . Spay::$appSecretKey;
            $headers['X-Spay-Sign'] = md5($toSign);
        }
        else
            throw new SpayParamaterException('app secret key is empty');

        if ($method === 'get' || $method === 'delete') {
            if ($method === 'get')
                $curlOpts[CURLOPT_HTTPGET] = true;
            if ($method === 'delete')
                $curlOpts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
            $curlOpts[CURLOPT_URL] = $url;
            $headers['X-Spay-Request-Data'] = $signedRequestBody;

        } elseif ($method === 'post' || $method === 'put') {
            if ($method === 'post')
                $curlOpts[CURLOPT_POST] = true;
            if ($method === 'put')
                $curlOpts[CURLOPT_CUSTOMREQUEST] = 'PUT';
            $curlOpts[CURLOPT_POSTFIELDS] = $signedRequestBody;
            $curlOpts[CURLOPT_URL] = $url;
        } else
            throw  new SpayParamaterException('not support method ' . $method);


        $toSendHeaders = [];
        foreach ($headers as $k => $v) {
            $toSendHeaders[] = $k . ': ' . $v;
        }
        $curlOpts[CURLOPT_TIMEOUT] = 30;
        $curlOpts[CURLOPT_RETURNTRANSFER] = true;
        $curlOpts[CURLOPT_HTTPHEADER] = $toSendHeaders;
        $curlOpts[CURLOPT_SSL_VERIFYPEER] = false;
        $curlOpts[CURLOPT_VERBOSE] = true;

        $ch = curl_init();
        curl_setopt_array($ch, $curlOpts);
        $result = curl_exec($ch);
        if ($result == false) {
            $error = curl_errno($ch);
            $msg = curl_error($ch);
            curl_close($ch);
            throw  new SpayCurlException("errorno:" . $error . " msg:" . $msg);
        }
        curl_close($ch);
        return $result;
    }

}